﻿using System;
using System.IO;
using System.Collections.Generic;
using EMANIFEST.DataAccess;
using EMANIFEST.Dtos;
using EMANIFEST.Cache;

namespace EMANIFEST.Services
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "EmanifestService" in code, svc and config file together.
    public class EmanifestService : IEmanifestService
    {
        private readonly BusinessDataAccess businessDataAccess = new BusinessDataAccess();

        #region Cache Utilities

        #endregion

        #region Private Utilities
        #region Property to Document
        private void AddPropertyToListDocument(List<DocumentDto> lstDoc)
        {
            foreach (DocumentDto doc in lstDoc)
            {
                AddPortToDocument(doc);
                AddDocumentTypeToDocument(doc);
                AddDocumentStatusToDocument(doc);
                AddShipToDocument(doc);
            }
        }
        private void AddPropertyToDocument(DocumentDto doc)
        {
            if (doc != null && doc.DocumentId != null && doc.DocumentId != Guid.Empty)
            {
                AddPortToDocument(doc);
                AddDocumentTypeToDocument(doc);
                AddDocumentStatusToDocument(doc);
                AddShipToDocument(doc);
                if (doc.GeneralDeclarations != null && doc.GeneralDeclarations.Count > 0)
                {
                    AddPropertyToListGeneralDeclaration(doc.GeneralDeclarations);
                }
            }
        }
        private void AddPortToDocument(DocumentDto doc)
        {
            #region add Port property
            Dictionary<Guid, PortDto> dicPort = GetDicPortInUsed();
            PortDto port = dicPort[doc.PortId];
            if (port == null)
            {
                port = GetPortById(doc.PortId);
            }
            if (port != null)
            {
                doc.Port = new PortDto
                {
                    PortId = port.PortId,
                    Name = port.Name,
                    Address = port.Address,
                    PortCode = port.PortCode,
                };
            }
            #endregion
        }
        private void AddDocumentTypeToDocument(DocumentDto doc)
        {
            #region add DocumentType property
            if (doc.DocumentTypeId != null && doc.DocumentTypeId.HasValue)
            {
                Dictionary<int, DocumentTypeDto> dicDocType = GetDicDocumentType();
                DocumentTypeDto docType = dicDocType[doc.DocumentTypeId.Value];
                if (docType != null)
                {
                    doc.DocumentType = new DocumentTypeDto
                    {
                        DocumentTypeId = docType.DocumentTypeId,
                        Name = docType.Name,
                        Description = docType.Description,
                    };
                }
            }
            #endregion
        }
        private void AddDocumentStatusToDocument(DocumentDto doc)
        {
            #region add DocumentStatus property
            List<DocumentStatusDto> lstDocStatus = GetListDocumentStatus();
            DocumentStatusDto docStatus = lstDocStatus.Find(delegate(DocumentStatusDto sta)
            {
                return sta.StatusId == doc.StatusId;
            });
            if (docStatus != null)
            {
                doc.DocumentStatus = new DocumentStatusDto
                {
                    StatusId = docStatus.StatusId,
                    StatusName = docStatus.StatusName,
                    Description = docStatus.Description,
                };
            }

            #endregion
        }
        private void AddShipToDocument(DocumentDto doc)
        {
            #region add Ship properties
            ShipDto ship = GetShipById(doc.ShipId);
            doc.Ship = ship;
            #endregion

            //#region add Ship properties (Ship.ShipType,  Ship.State)


            //List<ShipTypeDto> lstShipType = GetListShipType();
            //ShipTypeDto shipType = lstShipType.Find(delegate(ShipTypeDto st)
            //{
            //    return st.ShipTypeId == doc.Ship.ShipTypeId;
            //});
            //if (shipType != null)
            //{
            //    doc.Ship.ShipType = new ShipTypeDto
            //    {
            //        ShipTypeId = shipType.ShipTypeId,
            //        Description = shipType.Description,
            //    };
            //}
            //StateDto shipState = GetDicState()[doc.Ship.StateId];
            //if (shipState != null)
            //{
            //    doc.Ship.State = new StateDto
            //    {
            //        StateId = shipState.StateId,
            //        ShortName = shipState.ShortName,
            //        Name = shipState.Name,
            //    };
            //}
            //#endregion
        }
        #endregion

        #region Property to Ship
        private void AddPropertyToListShip(List<ShipDto> lstShip)
        {
            foreach (ShipDto ship in lstShip)
                AddPropertyToShip(ship);
        }

        private void AddPropertyToShip(ShipDto ship)
        {
            AddStateToShip(ship);
            AddShipTypeToShip(ship);
        }
        private void AddStateToShip(ShipDto ship)
        {
            StateDto shipState = GetDicState()[ship.StateId];
            if (shipState != null)
            {
                ship.State = new StateDto
                {
                    StateId = shipState.StateId,
                    ShortName = shipState.ShortName,
                    Name = shipState.Name,
                };
            }
        }
        private void AddShipTypeToShip(ShipDto ship)
        {
            List<ShipTypeDto> lstShipType = GetListShipType();
            ShipTypeDto shipType = lstShipType.Find(delegate(ShipTypeDto st)
            {
                return st.ShipTypeId == ship.ShipTypeId;
            });
            if (shipType != null)
            {
                ship.ShipType = new ShipTypeDto
                {
                    ShipTypeId = shipType.ShipTypeId,
                    Description = shipType.Description,
                };
            }
        }
        #endregion;

        #region Property to Passenger
        private void AddPropertyToListPassenger(List<PassengerDto> lstPass)
        {
            foreach (PassengerDto pass in lstPass)
                AddPropertyToPassenger(pass);
        }
        private void AddPropertyToPassenger(PassengerDto pass)
        {
            if (pass != null && pass.PassengerId != null && pass.PassengerId != Guid.Empty)
            {
                AddStateToPassenger(pass);
                AddPassportTypeToPassenger(pass);
                AddPortToPassenger(pass);
            }
        }
        private void AddStateToPassenger(PassengerDto pass)
        {
            StateDto shipState = this.GetDicState()[pass.StateId];
            if (shipState != null)
            {
                pass.State = new StateDto
                {
                    StateId = shipState.StateId,
                    ShortName = shipState.ShortName,
                    Name = shipState.Name,
                };
            }
        }
        private void AddPassportTypeToPassenger(PassengerDto pass)
        {
            List<PassportTypeDto> lstPass = this.GetListPassportType();
            Dictionary<string, PassportTypeDto> dicPass = new Dictionary<string, PassportTypeDto>(lstPass.Count);
            foreach (PassportTypeDto ptye in lstPass)
                dicPass.Add(ptye.PassportType, ptye);
            pass.PassportType = pass.PassportType.Trim();
            pass.PassportTypeDto = dicPass[pass.PassportType];
        }

        private void AddPortToPassenger(PassengerDto pass)
        {
            #region add Port property
            Dictionary<Guid, PortDto> dicPort = GetDicPortInUsed();
            PortDto port = null;
            #region PortOfEmbarkation
            if (string.IsNullOrEmpty(pass.PortNameOfEmbarkation))
            {
                port = dicPort[pass.PortIdOfEmbarkation];
                if (port == null)
                {
                    port = GetPortById(pass.PortIdOfEmbarkation);
                }
                if (port != null)
                    pass.PortNameOfEmbarkation = port.Name;
                else
                    pass.PortNameOfEmbarkation = string.Empty;
            }
            #endregion
            #region PortOfDisembarkation
            if (string.IsNullOrEmpty(pass.PortNameOfDisembarkation))
            {
                port = dicPort[pass.PortIdOfDisembarkation];
                if (port == null)
                {
                    port = GetPortById(pass.PortIdOfDisembarkation);
                }
                if (port != null)
                    pass.PortNameOfDisembarkation = port.Name;
                else
                    pass.PortNameOfDisembarkation = string.Empty;
            }
            #endregion
            #endregion
        }
        #endregion

        #region Property to Crew
        private void AddPropertyToListCrew(List<CrewDto> lstCrew)
        {
            foreach (CrewDto crew in lstCrew)
                AddPropertyToCrew(crew);
        }
        private void AddPropertyToCrew(CrewDto crew)
        {
            if (crew != null && crew.CrewId != null && crew.CrewId != Guid.Empty)
            {
                AddStateToCrew(crew);
                AddPassportTypeToCrew(crew);
            }
        }
        private void AddStateToCrew(CrewDto crew)
        {
            StateDto shipState = GetDicState()[crew.StateId];
            if (shipState != null)
            {
                crew.State = new StateDto
                {
                    StateId = shipState.StateId,
                    ShortName = shipState.ShortName,
                    Name = shipState.Name,
                };
            }
        }
        private void AddPassportTypeToCrew(CrewDto crew)
        {
            List<PassportTypeDto> lstPass = this.GetListPassportType();
            Dictionary<string, PassportTypeDto> dicPass = new Dictionary<string, PassportTypeDto>(lstPass.Count);
            foreach (PassportTypeDto pass in lstPass)
                dicPass.Add(pass.PassportType, pass);
            crew.PassportType = crew.PassportType.Trim();
            crew.PassportTypeDto = dicPass[crew.PassportType.Trim()];
        }
        #endregion

        #region Property to HouseBill
        private void AddPropertyToListHouseBill(List<HouseBillDto> lstHouse)
        {
            foreach (var house in lstHouse)
                AddPortsToHouseBill(house);
        }
        private void AddPropertyToHouseBill(HouseBillDto house)
        {
            if (house != null && house.HouseBillId != null && house.HouseBillId != Guid.Empty)
                AddPortsToHouseBill(house);
        }

        private void AddPortsToHouseBill(HouseBillDto house)
        {
            //PortDto port = GetPortById(house.PortIdOfDestination);
            house.PortOfDestination = GetPortById(house.PortIdOfDestination);
            if (string.IsNullOrEmpty(house.PortNameOfDestination))
                house.PortNameOfDestination = house.PortOfDestination.Name;

            //port = dicPort[house.PortIdOfLoad];
            house.PortOfLoad = GetPortById(house.PortIdOfLoad);
            if (string.IsNullOrEmpty(house.PortNameOfLoad))
                house.PortNameOfLoad = house.PortOfLoad.Name;

            //port = dicPort[house.PortIdOfUnload];
            house.PortOfUnload = GetPortById(house.PortIdOfUnload);
            if (string.IsNullOrEmpty(house.PortNameOfUnload))
                house.PortNameOfUnload = house.PortOfUnload.Name;

            //port = dicPort[house.PortIdOfTranship];
            house.PortOfTranship = GetPortById(house.PortIdOfTranship);
            if (string.IsNullOrEmpty(house.PortNameOfTranship))
                house.PortNameOfTranship = house.PortOfTranship.Name;
        }
        #endregion

        #region Property to General Declaration
        private void AddPropertyToListGeneralDeclaration(List<GeneralDeclarationDto> lstGeneral)
        {
            foreach (GeneralDeclarationDto general in lstGeneral)
                AddPropertyToGeneralDeclaration(general);
        }
        private void AddPropertyToGeneralDeclaration(GeneralDeclarationDto general)
        {
            if (general != null && general.GeneralDeclarationId != null && general.GeneralDeclarationId != Guid.Empty)
                AddPortsToGeneralDeclaration(general);
        }
        private void AddPortsToGeneralDeclaration(GeneralDeclarationDto general)
        {
            general.DeparturePort = GetPortById(general.DeparturePortId);

            if (string.IsNullOrEmpty(general.LastArrivalPortName) && general.LastArrivalPortId.HasValue)
            {
                PortDto port = GetPortById(general.LastArrivalPortId.Value);
                if (port != null)
                    general.LastArrivalPortName = port.Name;
                else
                    general.LastArrivalPortName = string.Empty;
            }
        }


        #endregion

        #region Property to DangerousGood
        private void AddPropertyToListDangerousGood(List<DangerousGoodDto> lstGood)
        {
            foreach (DangerousGoodDto good in lstGood)
            {
                AddPropertyToDangerousGood(good);
            }
        }
        private void AddPropertyToDangerousGood(DangerousGoodDto good)
        {
            if (good != null && good.DangerousGoodId != null && good.DangerousGoodId != Guid.Empty)
                AddPortToDangerousGood(good);
        }
        private void AddPortToDangerousGood(DangerousGoodDto good)
        {
            #region add Port property
            Dictionary<Guid, PortDto> dicPort = GetDicPortInUsed();
            PortDto port = null;
            #region PortOfLoad
            if (string.IsNullOrEmpty(good.PortNameOfLoad))
            {
                port = dicPort[good.PortOfLoad];
                if (port == null)
                {
                    port = GetPortById(good.PortOfLoad);
                }
                if (port != null)
                    good.PortNameOfLoad = port.Name;
                else
                    good.PortNameOfLoad = string.Empty;
            }
            #endregion
            #region PortOfUnload
            if (string.IsNullOrEmpty(good.PortNameOfUnload))
            {
                port = dicPort[good.PortOfUnload];
                if (port == null)
                {
                    port = GetPortById(good.PortOfUnload);
                }
                if (port != null)
                    good.PortNameOfUnload = port.Name;
                else
                    good.PortNameOfUnload = string.Empty;
            }
            #endregion
            #endregion
        }
        #endregion
        #endregion

        #region State

        public StateDto GetStateById(Guid id)
        {
            return businessDataAccess.GetStateById(id);
        }

        public List<StateDto> GetListState()
        {
            return new List<StateDto>(businessDataAccess.GetDicState().Values);
        }
        public Dictionary<Guid, StateDto> GetDicState()
        {
            //if (System.Web.HttpContext.Current.Cache[CacheKey.CacheNameOfListState] == null)
            //    System.Web.HttpContext.Current.Cache[CacheKey.CacheNameOfListState] = businessDataAccess.GetDicState(); ;
            //return (System.Web.HttpContext.Current.Cache[CacheKey.CacheNameOfListState] as Dictionary<Guid, StateDto>);             
            Dictionary<Guid, StateDto> dicRet = CacheLayer.Get<Dictionary<Guid, StateDto>>(CacheKey.CacheNameOfListState);
            if (dicRet == null)
            {
                dicRet = businessDataAccess.GetDicState();
                CacheLayer.Add(CacheKey.CacheNameOfListState, dicRet);
            }

            return dicRet;
        }

        #endregion

        #region ShipType

        public ShipTypeDto GetShipTypeById(Guid id)
        {
            return businessDataAccess.GetShipTypeById(id);
        }

        public List<ShipTypeDto> GetListShipType()
        {
            List<ShipTypeDto> lstRet = CacheLayer.Get<List<ShipTypeDto>>(CacheKey.CacheNameOfShipType);
            if (lstRet == null)
            {
                lstRet = businessDataAccess.GetListShipType();
                CacheLayer.Add(CacheKey.CacheNameOfShipType, lstRet);
            }

            return lstRet;
        }

        #endregion

        #region DocumentStatus

        public DocumentStatusDto GetDocumentStatusById(int id)
        {
            return businessDataAccess.GetDocumentStatusById(id);
        }

        public List<DocumentStatusDto> GetListDocumentStatus()
        {
            List<DocumentStatusDto> lstRet = CacheLayer.Get<List<DocumentStatusDto>>(CacheKey.CacheNameOfDocumentStatus);
            if (lstRet == null)
            {
                lstRet = businessDataAccess.GetListDocumentStatus();
                lstRet.Sort(delegate(DocumentStatusDto src, DocumentStatusDto des)
                {
                    return des.StatusId - src.StatusId;
                });
                CacheLayer.Add(CacheKey.CacheNameOfDocumentStatus, lstRet);
            }

            return lstRet;
        }

        #endregion

        #region DocumentType

        public DocumentTypeDto GetDocumentTypeById(int id)
        {
            return businessDataAccess.GetDocumentTypeById(id);
        }

        public List<DocumentTypeDto> GetListDocumentType()
        {
            return businessDataAccess.GetListDocumentType();
        }

        public Dictionary<int, DocumentTypeDto> GetDicDocumentType()
        {
            Dictionary<int, DocumentTypeDto> dicRet = CacheLayer.Get<Dictionary<int, DocumentTypeDto>>(CacheKey.CacheNameOfDocumentType);
            if (dicRet == null)
            {
                dicRet = businessDataAccess.GetDicDocumentType();
                CacheLayer.Add(CacheKey.CacheNameOfDocumentType, dicRet);
            }

            return dicRet;
        }
        #endregion


        #region ItemCodeVN

        public ItemCodeVNDto GetItemCodeVNByItemId(string itemid)
        {
            return businessDataAccess.GetItemCodeVNByItemId(itemid);
        }

        public List<ItemCodeVNDto> GetListItemCodeVN()
        {
            return businessDataAccess.GetListItemCodeVN();
        }

        #endregion

        #region PassportType

        public PassportTypeDto GetPassportTypeById(string passportType)
        {
            return businessDataAccess.GetPassportTypeById(passportType);
        }

        public List<PassportTypeDto> GetListPassportType()
        {
            List<PassportTypeDto> lstRet = CacheLayer.Get<List<PassportTypeDto>>(CacheKey.CacheNameOfPassportType);
            if (lstRet == null)
            {
                lstRet = businessDataAccess.GetListPassportType();
                CacheLayer.Add(CacheKey.CacheNameOfPassportType, lstRet);
            }
            return lstRet;
        }

        #endregion

        #region Port

        public PortDto GetPortById(Guid id)
        {
            Dictionary<Guid, PortDto> dicPort = GetDicPortInUsed();
            PortDto port = null;
            if (dicPort.ContainsKey(id))
            {
                port = dicPort[id];
            }
            else
            {
                port = businessDataAccess.GetPortById(id);

                //Refeshes cache
                dicPort = businessDataAccess.GetDicPortInUsed();
                CacheLayer.Add(CacheKey.CacheNameOfListPortInUsed, dicPort);
            }
            return port;
        }

        public PortDto GetPortByCode(string code)
        {
            Dictionary<string, PortDto> dicPort = GetDicPortInUsed2();
            PortDto port = null;
            if (dicPort.ContainsKey(code))
            {
                port = dicPort[code];
            }
            else
            {
                port = businessDataAccess.GetPortByCode(code);
                //Refeshes cache
                dicPort = businessDataAccess.GetDicPortInUsed2();
                CacheLayer.Add(CacheKey.CacheNameOfListPortInUsed2, dicPort);
            }
            return port;
        }

        public List<PortDto> GetListPort()
        {
            return businessDataAccess.GetListPortInVN();
        }

        public List<PortDto> GetListPortByStateId(Guid stateId)
        {
            return businessDataAccess.GetListPortByStateId(stateId);
        }

        public List<PortDto> GetListPortInVN()
        {
            List<PortDto> lstRet = CacheLayer.Get<List<PortDto>>(CacheKey.CacheNameOfListPortInVN);
            if (lstRet == null)
            {
                lstRet = businessDataAccess.GetListPortInVN();
                CacheLayer.Add(CacheKey.CacheNameOfListPortInVN, lstRet);
            }

            return lstRet;
        }

        public Dictionary<Guid, PortDto> GetDicPortInUsed()
        {
            Dictionary<Guid, PortDto> dicRet = CacheLayer.Get<Dictionary<Guid, PortDto>>(CacheKey.CacheNameOfListPortInUsed);
            if (dicRet == null)
            {
                dicRet = businessDataAccess.GetDicPortInUsed();
                CacheLayer.Add(CacheKey.CacheNameOfListPortInUsed, dicRet);
            }

            return dicRet;
        }

        #endregion

        #region ItemCode

        /// <summary>
        /// Get ItemCode by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ItemCodeDto GetItemCodeById(Guid id)
        {
            return businessDataAccess.GetItemCodeById(id);
        }

        /// <summary>
        /// Get list ItemCode by name
        /// </summary>
        /// <param name="ItemCodeName"></param>
        /// <returns></returns>
        public List<ItemCodeDto> GetListItemCode()
        {
            return businessDataAccess.GetListItemCode();
        }

        /// <summary>
        /// Save ItemCode
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveItemCode(ItemCodeDto itemCodeDto)
        {
            return businessDataAccess.SaveItemCode(itemCodeDto);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteItemCode(Guid id)
        {
            return businessDataAccess.DeleteItemCode(id);
        }

        #endregion

        #region Ship

        /// <summary>
        /// Get ship by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ShipDto GetShipById(Guid id)
        {
            //ShipDto ship = businessDataAccess.GetShipById(id);
            Dictionary<Guid, ShipDto> dicShip = GetDicShip();
            ShipDto ship = null;
            if (dicShip.ContainsKey(id))
                ship = dicShip[id];
            else
            {
                ship = businessDataAccess.GetShipById(id);
                dicShip.Add(id, ship);
                CacheLayer.Add(CacheKey.CacheNameOfShip, dicShip);
            }

            AddPropertyToShip(ship);
            return ship;
        }

        /// <summary>
        /// Get list ship by name
        /// </summary>
        /// <param name="shipName"></param>
        /// <returns></returns>
        public List<ShipDto> GetListShipByName(string shipName)
        {
            List<ShipDto> lstShip = businessDataAccess.GetListShip(shipName);
            AddPropertyToListShip(lstShip);
            return lstShip;
        }

        /// <summary>
        /// Get list ship
        /// </summary>
        /// <returns></returns>        
        public List<ShipDto> GetListShip()
        {
            return businessDataAccess.GetListShip();
        }

        private Dictionary<Guid, ShipDto> GetDicShip()
        {
            Dictionary<Guid, ShipDto> lstRet = CacheLayer.Get<Dictionary<Guid, ShipDto>>(CacheKey.CacheNameOfShip);
            if (lstRet == null)
            {
                lstRet = new Dictionary<Guid, ShipDto>();
                List<ShipDto> lst = businessDataAccess.GetListShip();
                foreach (ShipDto sh in lst)
                    lstRet.Add(sh.ShipId, sh);
                CacheLayer.Add(CacheKey.CacheNameOfShip, lstRet);
            }
            return lstRet;
        }

        /// <summary>
        /// Get list ship by createrId
        /// </summary>
        /// <param name="createrId"></param>
        /// <returns></returns>
        public List<ShipDto> GetListShipByCreaterId(Guid createrId)
        {
            List<ShipDto> lstShip = businessDataAccess.GetListShipByCreaterId(createrId);
            AddPropertyToListShip(lstShip);
            return lstShip;
        }

        /// <summary>
        /// Get list ship by agencyId
        /// </summary>
        /// <param name="agencyId"></param>
        /// <returns></returns>
        public List<ShipDto> GetListShipByAgency(int agencyId)
        {
            List<ShipDto> lstShip = businessDataAccess.GetListShipByAgency(agencyId);
            AddPropertyToListShip(lstShip);
            return lstShip;
        }
        /// <summary>
        /// Save ship
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveShip(ShipDto shipDto)
        {
            return businessDataAccess.SaveShip(shipDto);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteShip(Guid id)
        {
            return businessDataAccess.DeleteShip(id);
        }

        #endregion

        #region Document

        /// <summary>
        /// Get Document by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DocumentDto GetDocumentById(Guid id)
        {
            DocumentDto doc = businessDataAccess.GetDocumentById(id);
            AddPropertyToDocument(doc);
            return doc;
        }

        /// <summary>
        /// Get Document Detail
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DocumentDto GetDocumentDetail(Guid documentId, Guid userId)
        {
            DocumentDto doc = businessDataAccess.GetDocumentDetail(documentId, userId);
            AddPropertyToDocument(doc);
            return doc;
        }
        /// <summary>
        /// Get list Document by name
        /// </summary>
        /// <param name="DocumentName"></param>
        /// <returns></returns>
        public List<DocumentDto> GetListDocumentByName(string DocumentName)
        {
            return businessDataAccess.GetListDocument(DocumentName);
        }

        /// <summary>
        /// Get list Document
        /// </summary>
        /// <returns></returns>
        public List<DocumentDto> GetListDocument()
        {
            List<DocumentDto> lstRet = businessDataAccess.GetListDocument();
            AddPropertyToListDocument(lstRet);
            return lstRet;
        }

        /// <summary>
        /// Get list Document By UserId
        /// </summary>
        /// <returns></returns>
        public List<DocumentDto> GetListDocumentByUserId(Guid userId)
        {
            List<DocumentDto> lstRet = businessDataAccess.GetListDocumentByUserId(userId);

            AddPropertyToListDocument(lstRet);

            return lstRet;
        }
        /// <summary>
        /// Get list Document By UserId
        /// </summary>
        /// <returns></returns>
        public List<DocumentDto> GetListNewDocumentByUserId(Guid userId)
        {
            List<DocumentDto> lstRet = businessDataAccess.GetListDocumentByUserId(userId, true);

            AddPropertyToListDocument(lstRet);

            return lstRet;
        }

        /// <summary>
        /// Save Document
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveDocument(DocumentDto DocumentDto)
        {
            return businessDataAccess.SaveDocument(DocumentDto);
        }

        /// <summary>
        /// Update Document Status
        /// </summary>
        /// <returns></returns>
        public ResponseDto UpdateDocumentStatus(Guid documentId, int statusId)
        {
            return businessDataAccess.UpdateDocumentStatus(documentId, statusId);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteDocument(Guid id, Guid userId)
        {
            return businessDataAccess.DeleteDocument(id, userId);
        }

        /// <summary>
        /// Assign user to document
        /// </summary>
        /// <param name="docId">Document Id</param>
        /// <param name="userIDs">List of UserId</param>
        /// <returns>ResponseDto</returns>
        public ResponseDto AddUsersToDocument(Guid docId, List<UserInfomation> lstUserInfo)
        {
            return businessDataAccess.AddUsersToDocument(docId, lstUserInfo);
        }

        /// <summary>
        /// get list of user who was assigned to document
        /// </summary>
        /// <param name="docId">Document Id</param>        
        /// <returns>List of UserId</returns>
        public List<UserInfomation> GetListUserInDocument(Guid docId)
        {
            return businessDataAccess.GetListUserInDocument(docId);
        }


        public UserInfomation GetUserInfoByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetUserInfoByDocumentId(docId, userId);
        }

        public ResponseDto SendRequestToCustom(DocumentDto DocumentDto)
        {
            ResponseDto response = new ResponseDto { IsSuccess = true, ErroeMessage = string.Empty };
            return response;
        }

        #endregion

        #region GeneralDeclaration

        /// <summary>
        /// Get GeneralDeclaration by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public GeneralDeclarationDto GetGeneralDeclarationById(Guid id)
        {
            GeneralDeclarationDto general = businessDataAccess.GetGeneralDeclarationById(id);
            AddPropertyToGeneralDeclaration(general);
            return general;
        }

        /// <summary>
        /// Get GeneralDeclaration by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public GeneralDeclarationDto GetGeneralDeclarationByDocumentId(Guid id, Guid userId)
        {
            GeneralDeclarationDto general = businessDataAccess.GetGeneralDeclarationByDocumentId(id, userId);
            AddPropertyToGeneralDeclaration(general);
            return general;
        }

        /// <summary>
        /// Save GeneralDeclaration
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveGeneralDeclaration(GeneralDeclarationDto generalDeclarationDto)
        {
            return businessDataAccess.SaveGeneralDeclaration(generalDeclarationDto);
        }



        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteGeneralDeclaration(Guid id)
        {
            return new ResponseDto { IsSuccess = false, ErroeMessage = "No implementation" };
            //return businessDataAccess.DeleteGeneralDeclarationById(id);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteGeneralDeclarationByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeleteGeneralDeclarationByDocumentId(documentId, userId);
        }
        #endregion

        #region DangerousGood

        /// <summary>
        /// Get DangerousGood by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DangerousGoodDto GetDangerousGoodById(Guid id)
        {
            return businessDataAccess.GetDangerousGoodById(id);
        }

        /// <summary>
        /// Get DangerousGood by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DangerousGoodDto GetDangerousByDocumentId(Guid documentId, Guid userId)
        {
            DangerousGoodDto good = businessDataAccess.GetDangerousGoodByDocumentId(documentId, userId);
            AddPropertyToDangerousGood(good);
            return good;
        }

        /// <summary>
        /// Save DangerousGood
        /// </summary>
        /// <returns></returns>


        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteDangerousGood(Guid id)
        {
            //return new ResponseDto { IsSuccess = false, ErroeMessage = "No implementation" };
            return businessDataAccess.DeleteDangerousGoodById(id);
        }



        /// <summary>
        /// Save DangerousGood
        /// </summary>
        /// <returns></returns>


        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteDangerousGoodItemById(Guid id)
        {
            return businessDataAccess.DeleteDangerousGoodItemById(id);
        }


        public ResponseDto SaveDangerousGood(DangerousGoodDto dangerousGoodDto)
        {
            return businessDataAccess.SaveDangerousGood(dangerousGoodDto);
        }



        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteDangerousGoodByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeleteDangerousGoodByDocumentId(documentId, userId);
        }

        #region Paging
        public int GetDangerousGoodNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetDangerousGoodNumberByDocumentId(docId, userId);
        }

        public DangerousGoodPagingDto GetDangerousGoodPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            DangerousGoodPagingDto ret = businessDataAccess.GetDangerousGoodPagingByDocumentId(docId, userId, startIndex, pageSize);
            if (ret.lstItems != null && ret.lstItems.Count > 0)
                AddPropertyToListDangerousGood(ret.lstItems);
            return ret;
        }

        public int GetDangerousGoodItemNumberByDangerousGoodId(Guid houseId, Guid userId)
        {
            return businessDataAccess.GetDangerousGoodItemNumberByDangerousGoodId(houseId, userId);
        }


        public DangerousGoodItemPagingDto GetDangerousGoodItemPagingByDangerousGoodId(Guid houseId, Guid userId, int startIndex, int pageSize)
        {
            return businessDataAccess.GetDangerousGoodItemPagingByDangerousGoodId(houseId, userId, startIndex, pageSize);
        }
        #endregion

        #endregion

        #region ShipStoreDeclaration

        /// <summary>
        /// Get ShipStoreDeclaration by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ShipStoreDeclarationDto GetShipStoreDeclarationById(Guid id)
        {
            return businessDataAccess.GetShipStoreDeclarationById(id);
        }

        /// <summary>
        /// Save ShipStoreDeclaration
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveShipStoreDeclaration(ShipStoreDeclarationDto shipStoreDeclarationDto)
        {
            return businessDataAccess.SaveShipStoreDeclaration(shipStoreDeclarationDto);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteShipStoreDeclaration(Guid id)
        {
            return new ResponseDto { IsSuccess = false, ErroeMessage = "No Implementation" };
            //return businessDataAccess.DeleteShipStoreDeclarationById(id);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteShipStoreDeclarationByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeleteShipStoreDeclarationByDocumentId(documentId, userId);
        }
        //SaveShipStoreDeclarationRecord

        // DeleteShipStoreItem 
        public ResponseDto DeleteShipStoreItem(Guid id)
        {
            //return new ResponseDto { IsSuccess = false, ErroeMessage = "No implementation" };
            // return businessDataAccess
            return businessDataAccess.DeleteShipStoreItem(id);
        }

        #region Paging
        public int GetShipStoreNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetShipStoreDeclarationNumberByDocumentId(docId, userId);
        }

        public List<ShipStoreItemDto> GetShipStorePagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            return businessDataAccess.GetShipStoreDeclarationPagingByDocumentId(docId, userId, startIndex, pageSize);
        }
        #endregion
        #endregion

        #region GoodDeclaration

        /// <summary>
        /// Get GoodDeclaration by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public GoodDeclarationDto GetGoodDeclarationById(Guid id)
        {
            return businessDataAccess.GetGoodDeclarationById(id);
        }

        public GoodDeclarationDto GetGoodDeclarationByStrId(string strId)
        {
            Guid id;
            if (Guid.TryParse(strId, out id))
                return GetGoodDeclarationById(id);
            else
                return null;
        }
        /// <summary>
        /// Save GoodDeclaration
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveGoodDeclaration(GoodDeclarationDto goodDeclarationDto)
        {
            return businessDataAccess.SaveGoodDeclaration(goodDeclarationDto);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteGoodDeclaration(Guid id)
        {

            return businessDataAccess.DeleteGoodDeclaration(id);

        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteGoodDeclarationByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeleteGoodDeclarationByDocumentId(documentId, userId);
        }



        /// <summary>
        /// Import document - GoodDeclaration
        /// </summary>
        /// <param name="document">Document</param>        
        /// <returns>ResponseDto</returns>
        public ResponseDto ImportGoodDeclarationData(DocumentDto document, Guid userId, string userName)
        {
            return businessDataAccess.ImportGoodDeclarationData(document, userId, userName);
        }

        public ResponseDto DeleteGoodItem(Guid id)
        {
            return businessDataAccess.DeleteGoodItem(id);
        }

        #region Paging
        public int GetGoodItemNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetGoodItemNumberByDocumentId(docId, userId);
        }


        public List<GoodItemDto> GetGoodItemPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            return businessDataAccess.GetGoodItemPagingByDocumentId(docId, userId, startIndex, pageSize);
        }
        #endregion
        #endregion

        #region Crew

        /// <summary>
        /// Get Crew by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public CrewDto GetCrewById(Guid id)
        {
            return businessDataAccess.GetCrewById(id);
        }

        /// <summary>
        /// Get list Crew by name
        /// </summary>
        /// <param name="CrewName"></param>
        /// <returns></returns>
        public List<CrewDto> GetListCrew(Guid documentId, Guid userId, bool isTemp = false)
        {
            List<CrewDto> lstCrew = businessDataAccess.GetListCrew(documentId, userId);
            AddPropertyToListCrew(lstCrew);
            return lstCrew;
        }

        /// <summary>
        /// Save Crew
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveCrews(List<CrewDto> crewDtos, bool isTemp = false)
        {
            return businessDataAccess.SaveCrew(crewDtos, isTemp);
        }

        /// <summary>
        /// Save Crew
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveCrew(CrewDto crewDto, bool isTemp = false)
        {
            return businessDataAccess.SaveCrew(crewDto, isTemp);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteCrewById(Guid id)
        {
            businessDataAccess.DeleteCrewById(id);
            return new ResponseDto { IsSuccess = true, ErroeMessage = string.Empty };
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteCrewByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeleteCrewByDocumentId(documentId, userId);
        }



        #region Paging
        public int GetCrewNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetCrewNumberByDocumentId(docId, userId);
        }

        public List<CrewDto> GetCrewPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            List<CrewDto> lstRet = businessDataAccess.GetCrewPagingByDocumentId(docId, userId, startIndex, pageSize);
            AddPropertyToListCrew(lstRet);
            return lstRet;
        }
        #endregion
        #endregion

        #region CrewEffectDeclaration

        /// <summary>
        /// Get CrewEffectDeclaration by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public CrewEffectDeclarationDto GetCrewEffectDeclarationById(Guid id)
        {
            return businessDataAccess.GetCrewEffectDeclarationById(id);
        }

        /// <summary>
        /// Get list CrewEffectDeclaration by name
        /// </summary>
        /// <param name="CrewEffectDeclarationName"></param>
        /// <returns></returns>
        public List<CrewEffectDeclarationDto> GetListCrewEffectDeclaration(Guid documentId, Guid userId, bool isTemp = false)
        {
            return businessDataAccess.GetListCrewEffectDeclaration(documentId, userId);
        }


        /// <summary>
        /// Save CrewEffectDeclaration
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveCrewEffectDeclaration(List<CrewEffectDeclarationDto> CrewEffectDeclarationDtos, bool isTemp = false)
        {
            return businessDataAccess.SaveCrewEffectDeclaration(CrewEffectDeclarationDtos, isTemp);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteCrewEffectDeclarationById(Guid id)
        {
            businessDataAccess.DeleteCrewEffectDeclarationById(id);
            return new ResponseDto { IsSuccess = true, ErroeMessage = string.Empty };
            //return businessDataAccess.DeleteCrewEffectDeclarationById(id);
        }


        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>

        #region Paging
        public int GetCrewEffectNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetCrewEffectDeclarationNumberByDocumentId(docId, userId);
        }

        public List<CrewEffectDeclarationDto> GetCrewEffectPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            return businessDataAccess.GetCrewEffectDeclarationPagingByDocumentId(docId, userId, startIndex, pageSize);
        }
        #endregion
        #endregion

        #region Passenger

        /// <summary>
        /// Get Passenger by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public PassengerDto GetPassengerById(Guid id)
        {
            return businessDataAccess.GetPassengerById(id);
        }

        /// <summary>
        /// Get list Passenger by name
        /// </summary>
        /// <param name="PassengerName"></param>
        /// <returns></returns>
        public List<PassengerDto> GetListPassenger(Guid documentId, Guid userId, bool isTemp = false)
        {
            return businessDataAccess.GetListPassenger(documentId, userId);
        }

        /// <summary>
        /// Save Passenger
        /// </summary>
        /// <returns></returns>
        public ResponseDto SavePassenger(List<PassengerDto> passengerDtos, bool isTemp = false)
        {
            return businessDataAccess.SavePassenger(passengerDtos, isTemp);
        }



        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeletePassengerById(Guid id)
        {
            return businessDataAccess.DeletePassengerById(id);
            //return new ResponseDto { IsSuccess = true, ErroeMessage = string.Empty };
        }
        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeletePassengerByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeletePassengerByDocumentId(documentId, userId);
        }


        #region Paging
        public int GetPassengerNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetPassengerNumberByDocumentId(docId, userId);
        }

        public List<PassengerDto> GetPassengerPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            List<PassengerDto> lstPass = businessDataAccess.GetPassengerPagingByDocumentId(docId, userId, startIndex, pageSize);
            AddPropertyToListPassenger(lstPass);
            return lstPass;
        }
        #endregion
        #endregion

        #region HouseBill

        /// <summary>
        /// Get HouseBill by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public HouseBillDto GetHouseBillById(Guid id)
        {
            return businessDataAccess.GetHouseBillById(id);
        }


        /// <summary>
        /// Get HouseBill by documentId and userId
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<HouseBillDto> GetHouseBillByDocumentId(Guid docId, Guid userId)
        {
            List<HouseBillDto> hb = businessDataAccess.GetHouseBillByDocumentId(docId, userId);
            AddPropertyToListHouseBill(hb);
            return hb;
        }

        public HouseBillDto GetHouseBillByStrId(string strId)
        {
            Guid id;
            if (Guid.TryParse(strId, out id))
                return GetHouseBillById(id);
            else
                return null;
        }
        /// <summary>
        /// Save HouseBill
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveHouseBill(HouseBillDto houseBillDto)
        {
            PortDto port = null;
            if (houseBillDto.PortIdOfDestination == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfDestination);
                if (port != null)
                {
                    houseBillDto.PortIdOfDestination = port.PortId;
                    houseBillDto.PortNameOfDestination = port.Address;
                }
            }
            if (houseBillDto.PortIdOfLoad == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfLoad);
                if (port != null)
                {
                    houseBillDto.PortIdOfLoad = port.PortId;
                    houseBillDto.PortNameOfLoad = port.Address;
                }
            }
            if (houseBillDto.PortIdOfUnload == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfUnload);
                if (port != null)
                {
                    houseBillDto.PortIdOfUnload = port.PortId;
                    houseBillDto.PortNameOfUnload = port.Address;
                }

            }
            if (houseBillDto.PortIdOfTranship == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfTranship);
                if (port != null)
                {
                    houseBillDto.PortIdOfTranship = port.PortId;
                    houseBillDto.PortNameOfTranship = port.Address;
                }
            }
            return businessDataAccess.SaveHouseBill(houseBillDto);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteHouseBill(Guid id)
        {
            //  return new ResponseDto { IsSuccess = false, ErroeMessage = "No implementation" };
            return businessDataAccess.DeleteHouseBill(id);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteHouseBillByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeleteHouseBillByDocumentId(documentId, userId);
        }

        public ResponseDto SaveHouseBillItem(HouseBillItemDto houseBillItem)
        {
            return businessDataAccess.SaveHouseBillItem(houseBillItem);
        }

        public ResponseDto DeleteHouseBillItem(Guid id)
        {
            return businessDataAccess.DeleteHouseBillItem(id);
        }

        #region Paging

        public int GetHouseBillNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetHouseBillNumberByDocumentId(docId, userId);
        }

        public List<HouseBillDto> GetHouseBillPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            List<HouseBillDto> lstHouseBills = businessDataAccess.GetHouseBillPagingByDocumentId(docId, userId, startIndex, pageSize);
            AddPropertyToListHouseBill(lstHouseBills);
            return lstHouseBills;
        }

        public int GetHouseBillItemNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetHouseBillItemNumberByDocumentId(docId, userId);
        }

        public List<HouseBillItemDto> GetHouseBillItemPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            return businessDataAccess.GetHouseBillItemPagingByDocumentId(docId, userId, startIndex, pageSize);
        }

        public int GetHouseBillItemNumberByHouseBillId(Guid houseId, Guid userId)
        {
            return businessDataAccess.GetHouseBillItemNumberByHouseBillId(houseId, userId);
        }


        public List<HouseBillItemDto> GetHouseBillItemPagingByHouseBillId(Guid houseId, Guid userId, int startIndex, int pageSize)
        {
            return businessDataAccess.GetHouseBillItemPagingByHouseBillId(houseId, userId, startIndex, pageSize);
        }


        #endregion
        #endregion


        #region Document History
        public DocumentHistoryDto GetDocumentHistory(Guid documentId, int statusId)
        {
            return businessDataAccess.GetDocumentHistory(documentId, statusId);
        }

        public List<DocumentHistoryDto> GetListDocumentHistoryByDocId(Guid documentId, Guid userId)
        {
            return businessDataAccess.GetListDocumentHistoryByDocId(documentId, userId);
        }

        public ResponseDto SaveDocumentHistoryUI(Guid documentId, string name, string description)
        {

            return businessDataAccess.SaveDocumentHistoryUI(documentId, name, description);

        }
        #endregion

        #region EDI
        public ResponseDto SaveEdiFile(EdiUploadFileDto edi)
        {
            return businessDataAccess.SaveEdiUploadFile(edi);
        }


        public EdiUploadFileDto GetEdiFileById(Guid ediId)
        {
            return businessDataAccess.GetEdiFileById(ediId);
        }


        #endregion

        #region Guarantee Users

        public List<Guid> GetListUserIdByCreaterId(Guid createrId)
        {
            return businessDataAccess.GetListUserIdByCreaterId(createrId);
        }

        public ResponseDto SaveGuaranteeUser(UsersGuaranteeUserDto guaUser)
        {
            return businessDataAccess.SaveGuaranteeUser(guaUser);
        }
        #endregion

        #region MasterBill

        /// <summary>
        /// Get MasterBill by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public MasterBillDto GetMasterBillById(Guid id)
        {
            return businessDataAccess.GetMasterBillById(id);
        }

        /// <summary>
        /// Get MasterBill by id of document and user id
        /// </summary>
        /// <param name="docId"> Document Id</param>
        /// <param name="userId"> User Id</param>
        /// <returns></returns>
        public List<MasterBillDto> GetListMasterBillByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetListMasterBillByDocumentId(docId, userId);
        }

        /// <summary>
        /// Save MasterBill
        /// </summary>
        /// <returns></returns>
        public ResponseDto SaveMasterBill(MasterBillDto billDto)
        {
            return businessDataAccess.SaveMasterBill(billDto);
        }

        /// <summary>
        /// Delete object
        /// </summary>
        /// <returns></returns>
        public ResponseDto DeleteMasterBill(Guid id)
        {
            return new ResponseDto { IsSuccess = false, ErroeMessage = "No implementation" };
            //return businessDataAccess.DeleteMasterBillById(id);
        }

        public
        int GetMasterBillNumberByDocumentId(Guid docId, Guid userId)
        {
            return businessDataAccess.GetMasterBillNumberByDocumentId(docId, userId);
        }

        public List<MasterBillDto> GetMasterBillPagingByDocumentId(Guid docId, Guid userId, int startIndex, int pageSize)
        {
            return businessDataAccess.GetMasterBillPagingByDocumentId(docId, userId, startIndex, pageSize);
        }

        #endregion

        #region Container

        public ResponseDto SaveContainer(ContainerDto containerDto)
        {
            return businessDataAccess.SaveContainer(containerDto);
        }

        public ResponseDto SaveListContainer(List<ContainerDto> lstContainerDto)
        {
            return businessDataAccess.SaveListContainer(lstContainerDto);
        }

        #endregion

        #region search
        public List<ShipDto> SearchShip(ShipFilter filter)
        {
            List<ShipDto> lstShip = businessDataAccess.SearchShip(filter);
            AddPropertyToListShip(lstShip);
            return lstShip;
        }

        public List<DocumentDto> SearchDocument(DocumentFilter filter)
        {
            List<DocumentDto> lstDoc = businessDataAccess.SearchDocument(filter);
            AddPropertyToListDocument(lstDoc);
            return lstDoc;
        }

        public List<DocumentDto> SearchDocumentAccept(DocumentFilter filter)
        {
            List<DocumentDto> lstDoc = businessDataAccess.SearchDocumentAccept(filter);
            AddPropertyToListDocument(lstDoc);
            return lstDoc;
        }

        public List<DocumentDto> SearchDocumentNoAccepted(DocumentFilter filter)
        {
            List<DocumentDto> lstDoc = businessDataAccess.SearchDocumentNoAccepted(filter);
            AddPropertyToListDocument(lstDoc);
            return lstDoc;
        }

        public ResponseDto SaveNoticeShipTo(NoticeShipToDto notice)
        {
            return businessDataAccess.SaveNoticeShipTo(notice);
        }


        public GoodDeclarationDto GetGoodDeclarationByDocumentId(Guid id, Guid userId)
        {
            return businessDataAccess.GetGoodDeclarationByDocumentId(id, userId);
        }

        public ShipStoreDeclarationDto GetShipStoreDeclarationByDocumentId(Guid id, Guid userId)
        {
            return businessDataAccess.GetShipStoreDeclarationByDocumentId(id, userId);
        }

        #endregion

        #region DocumentChange
        public ResponseDto SendRequestEditDocument(DocumentChangeDto document)
        {
            return businessDataAccess.SendRequestEditDocument(document);
        }

        public List<DocumentChangeDto> GetListDocumentChangeByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.GetListDocumentChangeByDocumentId(documentId, userId);
        }

        public List<DocumentDto> SearchDocumentChange(DocumentFilter filter)
        {
            List<DocumentDto> lstDoc = businessDataAccess.SearchDocumentChange(filter);
            AddPropertyToListDocument(lstDoc);
            return lstDoc;
        }
        #endregion


        #region EDI Utils
        public ResponseDto UpdateStatusAfterBatchInEDIUploadFileById(Guid ediId, int status)
        {
            return businessDataAccess.UpdateStatusAfterBatchInEDIUploadFileById(ediId, status);
        }

        #endregion


        #region private util methods
        private Dictionary<string, PortDto> GetDicPortInUsed2()
        {
            Dictionary<string, PortDto> dicRet = CacheLayer.Get<Dictionary<string, PortDto>>(CacheKey.CacheNameOfListPortInUsed2);
            if (dicRet == null)
            {
                dicRet = businessDataAccess.GetDicPortInUsed2();
                CacheLayer.Add(CacheKey.CacheNameOfListPortInUsed2, dicRet);
            }

            return dicRet;
        }

        private PortDto GetPortByName(string portName)
        {
            return GetPortByCode(portName);
        }
        #endregion

        #region Save Record

        //SaveGeneralDeclarationRecord
        public ResponseDto SaveGeneralDeclarationRecord(GeneralDeclarationDto generalDeclarationDto)
        {
           
            return businessDataAccess.SaveGeneralDeclarationRecord(generalDeclarationDto);
        }



        public ResponseDto SaveDangerousGoodRecord(DangerousGoodDto good)
        {

            PortDto port = null;
            if (good.PortOfLoad == Guid.Empty)
            {
                port = GetPortByName(good.PortNameOfLoad);
                if (port != null)
                {
                    good.PortOfLoad = port.PortId;
                    good.PortNameOfLoad = port.Address;
                }
            }
            if (good.PortOfUnload == Guid.Empty)
            {
                port = GetPortByName(good.PortNameOfUnload);
                if (port != null)
                {
                    good.PortOfUnload = port.PortId;
                    good.PortNameOfUnload = port.Address;
                }
            }
            return businessDataAccess.SaveDangerousGoodRecord(good);
        }
        public ResponseDto SaveShipStoreDeclarationRecord(ShipStoreDeclarationDto shipStoreDeclarationDto)
        {
            return businessDataAccess.SaveShipStoreDeclarationRecord(shipStoreDeclarationDto);
        }

        //SaveCrewRecord
        public ResponseDto SaveCrewRecord(CrewDto crewDtos)
        {
            return businessDataAccess.SaveCrewRecord(crewDtos);
        }
        // Save 1 record 
        public ResponseDto SaveCrewEffectDeclarationRecord(CrewEffectDeclarationDto crewEffectDeclarationDto)
        {
            return businessDataAccess.SaveCrewEffectDeclarationRecord(crewEffectDeclarationDto);
        }

        public ResponseDto DeleteCrewEffectDeclarationByDocumentId(Guid documentId, Guid userId)
        {
            return businessDataAccess.DeleteCrewEffectDeclarationByDocumentId(documentId, userId);
        }

        public ResponseDto SavePassengerRecord(PassengerDto passengerDtos)
        {
            PortDto port = null;
            if (passengerDtos.PortIdOfEmbarkation == Guid.Empty)
            {
                port = GetPortByName(passengerDtos.PortNameOfEmbarkation);
                if (port != null)
                {
                    passengerDtos.PortIdOfEmbarkation = port.PortId;
                    passengerDtos.PortNameOfEmbarkation = port.Address;
                }
            }
            if (passengerDtos.PortIdOfDisembarkation == Guid.Empty)
            {
                port = GetPortByName(passengerDtos.PortNameOfDisembarkation);
                if (port != null)
                {
                    passengerDtos.PortIdOfDisembarkation = port.PortId;
                    passengerDtos.PortNameOfDisembarkation = port.Address;
                }
            }
            return businessDataAccess.SavePassengerRecord(passengerDtos);
        }

        // SaveHouseBillRecord
        public ResponseDto SaveHouseBillRecord(HouseBillDto houseBillDto)
        {
            PortDto port = null;
            if (houseBillDto.PortIdOfDestination == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfDestination);
                if (port != null)
                {
                    houseBillDto.PortIdOfDestination = port.PortId;
                    houseBillDto.PortNameOfDestination = port.Address;
                }
            }
            if (houseBillDto.PortIdOfLoad == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfLoad);
                if (port != null)
                {
                    houseBillDto.PortIdOfLoad = port.PortId;
                    houseBillDto.PortNameOfLoad = port.Address;
                }
            }
            if (houseBillDto.PortIdOfUnload == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfUnload);
                if (port != null)
                {
                    houseBillDto.PortIdOfUnload = port.PortId;
                    houseBillDto.PortNameOfUnload = port.Address;
                }

            }
            if (houseBillDto.PortIdOfTranship == Guid.Empty)
            {
                port = GetPortByName(houseBillDto.PortNameOfTranship);
                if (port != null)
                {
                    houseBillDto.PortIdOfTranship = port.PortId;
                    houseBillDto.PortNameOfTranship = port.Address;
                }
            }
            return businessDataAccess.SaveHouseBillRecord(houseBillDto);

        }

        public ResponseDto SaveHouseBillItemRecord(HouseBillItemDto houseBillItem)
        {
            return businessDataAccess.SaveHouseBillItemRecord(houseBillItem);
        }
        public ResponseDto SaveDangerousGoodItemRecord(DangerousGoodItemDto dangerousGoodItemDto)
        {
            return businessDataAccess.SaveDangerousGoodItemRecord(dangerousGoodItemDto);
        }

        public ResponseDto SaveShipStoreItemRecord(ShipStoreItemDto shipStoreItemDto)
        {
            return businessDataAccess.SaveShipStoreItemRecord(shipStoreItemDto);
        }
        public ResponseDto SaveGoodItemRecord(GoodItemDto goodItemDto)
        {
            return businessDataAccess.SaveGoodItemRecord(goodItemDto);
        }
        public ResponseDto SaveGoodDeclarationRecord(GoodDeclarationDto goodDeclarationDto)
        {
            return businessDataAccess.SaveGoodDeclarationRecord(goodDeclarationDto);
        }
        #endregion


        public ResponseDto ImportGoodDeclarationDataXML(Stream content)
        {
            ResponseDto ret = new ResponseDto() { IsSuccess = true, ErroeMessage = string.Empty };
            {
                ret = businessDataAccess.ImportEDIDataXML(content, 1);
                content.Dispose();
            }
            //#region save to file
            //string filename = @"H:\ImportGoodDeclarationDataXML2.xml";
            //try
            //{
            //    int length = 256;
            //    int bytesRead = 0;
            //    Byte[] buffer = new Byte[length];

            //    // write the required bytes
            //    using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
            //    {
            //        do
            //        {
            //            bytesRead = content.Read(buffer, 0, length);
            //            fs.Write(buffer, 0, bytesRead);
            //        }
            //        while (bytesRead > 0);
            //    }
            //    //ret = businessDataAccess.ImportGoodDeclarationDataXML(content);
            //    content.Dispose();

            //}
            //catch
            //{
            //}
            //#endregion
            return ret;
        }

        public ResponseDto ImportMasterBillDataXML(Stream content)
        {
            ResponseDto ret = new ResponseDto() { IsSuccess = true, ErroeMessage = string.Empty };
            //{
            //    ret = businessDataAccess.ImportEDIDataXML(content, 11);
            //    content.Dispose();
            //}
            //#region save to file
            //string filename = @"H:\ImportMasterBillDataXML2.xml";
            //try
            //{
            //    int length = 256;
            //    int bytesRead = 0;
            //    Byte[] buffer = new Byte[length];

            //    // write the required bytes
            //    using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
            //    {
            //        do
            //        {
            //            bytesRead = content.Read(buffer, 0, length);
            //            fs.Write(buffer, 0, bytesRead);
            //        }
            //        while (bytesRead > 0);
            //    }
            //    //ret = businessDataAccess.ImportGoodDeclarationDataXML(content);
            //    content.Dispose();

            //}
            //catch
            //{
            //}
            //#endregion
            return ret;
        }

        public ResponseDto ImportContainerDataXML(Stream content)
        {
            ResponseDto ret = new ResponseDto() { IsSuccess = true, ErroeMessage = string.Empty };
            //{
            //    ret = businessDataAccess.ImportEDIDataXML(content, 12);
            //    content.Dispose();
            //}
            return ret;
        }

    }
}
